package com.xtaller.easy.admin.controller.unauth;

import com.alibaba.fastjson.JSONObject;
import com.xtaller.common.bean.AuthInfo;
import com.xtaller.common.bean.CacheInfo;
import com.xtaller.common.bean.JWTResult;
import com.xtaller.common.convert.J;
import com.xtaller.common.convert.S;
import com.xtaller.common.convert.V;
import com.xtaller.common.convert.W;
import com.xtaller.common.kit.JwtKit;
import com.xtaller.common.kit.MD5Kit;
import com.xtaller.easy.admin.base.TApi;
import com.xtaller.easy.admin.config.R;
import com.xtaller.easy.admin.model.BaseUser;
import com.xtaller.easy.admin.service.impl.BaseUserService;
import com.xtaller.easy.admin.specification.UserLogin;
import com.xtaller.easy.admin.tps.CacheKit;
import io.jsonwebtoken.Claims;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Taller on 2018/4/13
 */
@Api(tags = "公共api")
@RestController
@RequestMapping("/v1/common")
@CrossOrigin   //跨域服务注解
public class CommonApi extends TApi {
    @Autowired
    private BaseUserService userService;

    // 登录校验
    private Map<String,String> loginVerify(){
        Map<String,String> verify = new HashMap<>();
        verify.put("loginName","登录账号不能为空");
        verify.put("password","登录密码不能为空");
        verify.put("platform","登录平台类型不能为空");
        return verify;
    }

    @PostMapping("/login")
    @ApiOperation(value = "用户登录")
    public Object userLogin(@RequestBody UserLogin model){
        JSONObject check = V.checkEmpty(loginVerify(), model);
        if(check.getBoolean("check"))
            return R.error(check.getString("message"));
        if(model.getPlatform() > 3 || model.getPlatform() < 0)
            return R.error("平台数据有误");
        BaseUser user = userService.queryOne(W.f(
                W.and("loginName", "eq", model.getLoginName())
        ));
        if(user == null)
            return R.error("登录账号或登录密码有误");
        // 处理数据
        String salt = user.getSalt();
        String inputPwd = MD5Kit.encode(S.apppend(model.getPassword(), salt));
        String oldPwd = user.getPassword();
        // 密码比较
        if(!V.isEqual(inputPwd, oldPwd))
            return R.error("登录账号或登录密码有误");
        // 读取用户信息
        JSONObject object = getUserInfo(user.getId(), model.getModule());
        if(object.getInteger("check") == -1)
            return R.error(HttpStatus.FORBIDDEN, "当前尚未给账号分配角色权限");
        // 生成jwt
        String jwt = JwtKit.createJWT(
                user.getId()+"",
                new AuthInfo(model.getPlatform(), "9527", "20180303", model.getModule()),
                0);

        // 缓存检查/缓存数据
        CacheInfo info = cacheKit.getCacheInfo(user.getId());
        info.setData(object);
        info.setJwt(model.getPlatform(), jwt);
        // redis 缓存info数据
        cacheKit.setVal(user.getId(), info);
        object.put("token", jwt);
        object.put("loginName", model.getLoginName());
        return R.ok("登录成功", object);
    }

    @GetMapping("/check")
    @ApiOperation(value = "检查Token的有效性/刷新用户信息")
    public Object checkToken(){
        String token = getToken();
        JWTResult jwt = JwtKit.validateJWT(token);
        if (jwt.isSuccess()) {
            Claims claims = jwt.getClaims();
            BaseUser user = userService.selectById(claims.getId());
            if(user == null)
                return R.error(HttpStatus.FORBIDDEN, "签名异常", 1);
            AuthInfo auth = J.s2m(claims.getSubject(), AuthInfo.class);
            auth.setId(user.getId());
            // 缓存检查
            CacheInfo info = cacheKit.getCacheInfo(user.getId());
            if(info == null)
                return R.error(HttpStatus.FORBIDDEN, "缓存信息丢失请重新登录", 1);

            // 单点登录检测
            JSONObject v = null;
            try{
                v = info.checkJwt(auth.getPlatform(), token);
            }catch (Exception ex){
                return R.error(HttpStatus.FORBIDDEN, "签名认证过期,请重新登录", 1);
            }
            if(!v.getBoolean("check")){
                return R.error(HttpStatus.FORBIDDEN, v.getString("message"), 1);
            }

            // 更新缓存数据
            JSONObject object = getUserInfo(user.getId(), auth.getModule());
            if(object.getInteger("check") == -1)
                return R.error(HttpStatus.FORBIDDEN, "账号角色权限被回收");

            info.setData(object);
            object.put("token", token);
            object.put("loginName", user.getLoginName());
            cacheKit.setVal(user.getId(), info);
            return R.ok("数据更新成功", object);
        } else {
            switch (jwt.getErrCode()) {
                // 签名验证不通过
                case 4002:
                    return R.error(HttpStatus.FORBIDDEN, "签名验证不通过", 1);
                // 签名过期
                case 4001:
                    return R.error(HttpStatus.FORBIDDEN, "签名过期", 1);
                default:
                    return R.error(HttpStatus.FORBIDDEN, "签名异常", 1);
            }
        }
    }

}
